
import imaplib
import smtplib
import email
import re
import sys
import location
import culinary
import foodtime
import util

from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText


def get_new_messages():
    """
    Assumes an email account that has access to potentially interesting emails
    Returns a dictionary, key'ed of the IMAP message ID, with a tuple of subject and body text
    """
    msg_dict = {}
    try:
        c = imaplib.IMAP4_SSL('imap.gmail.com')
        c.login(util.imap_uname,util.imap_pwd)
    except:
        print 'Problems connecting to IMAP server'
        return msg_dict
    
    try:
        c.select()             #by default, this selects the inbox
        typ, unseen_msgs = c.search(None,'(UNSEEN)')       #gives a list of unseen message IDs
        
        for msg_id in unseen_msgs[0].split():
            typ, msg_data = c.fetch(msg_id, '(RFC822)')
            full_email = email.message_from_string(msg_data[0][1])
            
            subject = full_email['Subject']
            #print subject
            body_text = ""
            body_html = ""
            #print full_email.get_content_type() 
            if full_email.is_multipart():
                for part in full_email.walk():
                    if part.get_content_type() ==  "text/plain":
                        cur_str = str(part.get_payload(decode=True))     #.strip()
                        cur_str = cur_str.replace('*','')             #common in text/plain for emphasis
                        if cur_str:
                            body_text += cur_str
                    if part.get_content_type() ==  "text/html":
                        cur_str = str(part.get_payload(decode=True))     #.strip()
                        cur_str = cur_str.replace('*','')             #common in text/plain for emphasis
                        if cur_str:
                            body_html += cur_str                            
            if len(body_html) < len(body_text): body_html=body_text     #we got only part of email, so retreat to text.
            body_text = subject + '\n' + body_text              #sometimes, only subject emails announce food.
            msg_dict[msg_id] = (subject, body_text, body_html)
         
    finally:
        try:
            c.close()
        except:
            pass
        c.logout()
        
    return msg_dict        
    
def get_postworthy():
    msg_dict = get_new_messages()
    print '%s new messages.' % len(msg_dict)
    post_list = []
    for msg_id in msg_dict:
        subj = msg_dict[msg_id][0]
        body_text = msg_dict[msg_id][1]
        body_html = msg_dict[msg_id][2]
        try:
            food_status = culinary.check_free_food(body_text)
            if food_status[0]:
                meal, meal_type = food_status[2]
                when = foodtime.get_food_time(body_text)
                where = location.location_of_food(body_text, location.buildings)
                
                subj_cleaner = re.compile('re:|fwd:|fw:',re.I)
                subj = subj_cleaner.sub('', subj)
                
                
                #also remove any email address from the listing
                addr_cleaner = re.compile('[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}', re.I)
                body_text = addr_cleaner.sub('email@removed.com',body_text)
                body_html = addr_cleaner.sub('email@removed.com',body_html)
                new_subj = ''
                if meal: new_subj += meal.upper().strip() + '|'
                else: new_subj += 'FOOD'
                if meal_type: 
                    if new_subj.lower() != meal_type.lower():
                        new_subj += '|' + meal_type.lower().strip() + '|'       
                if where: 
                    if new_subj[-1] != '|': new_subj += '|'
                    new_subj += where
                if when: 
                    if new_subj[-1] != '|': new_subj += '|'
                    new_subj += when
                    
                if new_subj[-1] != '|': new_subj += '|'
                new_subj += subj
                post_list.append((new_subj, body_text, body_html))
        except:
            print 'Error processing a message'
            print sys.exc_info()
                
    return post_list

def post_tweets(post_list):
    
    gmail_user = util.smtp_uname
    gmail_pwd = util.smtp_pwd
    try:
        smtpserver = smtplib.SMTP("smtp.gmail.com",587)
        smtpserver.ehlo()
        smtpserver.starttls()
        smtpserver.ehlo
        smtpserver.login(gmail_user, gmail_pwd)    
    except:
        print sys.exc_info()
        print 'Problems connecting to SMTP server'
        return
    to = 'post@posterous.com'  
    counter = 1
    for (subj, body_text, body_html) in post_list:
        msg = MIMEMultipart('alternative')
        msg['Subject'] = subj
        msg['From'] = gmail_user
        msg['To'] = to        
        part1 = MIMEText(body_text, 'plain')
        part2 = MIMEText(body_html, 'html')
        msg.attach(part1)
        msg.attach(part2)
        try:
            smtpserver.sendmail(gmail_user, to, msg.as_string())
            print 'Tweeted message: %s' % counter
            counter += 1
        except:
            print 'Error posting tweets'
            print sys.exc_info()
    smtpserver.close()
    
def drive():
    print 'Checking for messages.'
    post_list = get_postworthy()
    print '%s free food emails.' % len(post_list)
    post_tweets(post_list)
    
if __name__=='__main__':
    drive()
    
    
    
    
    
    
    
    
    